Lazy Load Content in Rails from Scratch
Are certain pages on your Rails app loading slowly? You might want to consider loading those requests in the background. It’s easier than you think. In this tutorial I’ll show you how to lazy load content in Rails without Hotwire.
Formula
-
Create an endpoint that does not return a layout.
-
Add a placeholder element onto the page that will represent where the content will be loaded.
-
Make a Fetch request to the endpoint and replace the placeholder with the response from the endpoint.
Example
Step 1: Create Endpoints
-
Generate namespaced controllers.
-
Add namespaced routes with default values.
-
Build controller actions.
-
Build views.
Card
Placeholder Card Variant
List Group
Post
User
What’s Going On Here?
- We create a namespaced route and controller. This isn’t required, but it helps keep our endpoints organized. We’re also not limited to just
index
actions either.- We set a default for those endpoints to not render a layout. This means that just the raw HTML for the partials will be returned.
- We choose to create custom views for each endpoint, but we could use the existing views or partials if we wanted to. This is just personal preference.
If you navigate to http://localhost:3000/lazy_load/users you should see that the content has loaded without a layout.
If you open the network tab you will see that the server responded with raw HTML without a layout.
Step 2: Build a Stimulus Controller
-
Create a Stimulus Controller to fetch data from the endpoints.
-
Use the following markup to connect to the Stimulus Controller.
What’s Going On Here?
- We could just use vanilla JavaScript instead of Stimulus, but Stimulus pairs nicely with Rails and will make it easy to get up and running with this feature quickly.
- When the Stimulus Controller first connects, it will make a fetch request to whatever value is stored in the
data-lazy-load-url-value
attribute. This keeps our Stimulus Controller flexible and reusable.- If the request was successful we replace the placeholder with the response. Note that we call response.text() in order to return the response into a String.
- If the request was not successful, we simply replace the placeholder with an error message.
- In all cases we dispatch a custom event on the
document
. We could call this event anything we want, but it’s helpful to namespace it to avoid naming collisions with other libraries or specs. This is what Rails UJS does, and is helpful in cases where you need to re-initialize JavaScript for elements that were just added to the DOM. In our case this is helpful for re-initializing tooltips.
Step 2: Putting it all Together
-
Create a new Controller.
rails g controller Homescreens show
-
Update the routes.
-
Add markup to lazy load content users and posts.